/*
 * BdbStorage
 * Created: Dec 29, 2006 
 * by abargnesi<mailto:abargnesi@aquent.com/>
 */
package com.den4.jynform;

import java.io.File;
import java.util.Map;
import java.util.TreeMap;

import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.serial.SerialBinding;
import com.sleepycat.bind.serial.StoredClassCatalog;
import com.sleepycat.je.Cursor;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.LockMode;
import com.sleepycat.je.OperationStatus;

public class BdbStorage implements JobStorage {
    private File dbLocation;
    private Environment env;
    private Database db;
    
    public BdbStorage(File dbLocation) {
        this.dbLocation = dbLocation;
    }
    
    public boolean connectStorage() {
        try {
            EnvironmentConfig envConfig = new EnvironmentConfig();
            envConfig.setAllowCreate(true);
            env = new Environment(dbLocation, envConfig);
            DatabaseConfig dbConfig = new DatabaseConfig();
            dbConfig.setAllowCreate(true);
            db = env.openDatabase(null, "db_jobs", dbConfig);
        } catch (DatabaseException dbe) {
            dbe.printStackTrace();
            return false;
        }
        return true;
    }
    
    public boolean disconnectStorage() {
        try {
            if (db != null) db.close();
            if (env != null) env.close();
        } catch (DatabaseException dbe) {
            dbe.printStackTrace();
            return false;
        }
        return true;
    }
    
    public JobBean getJob(JobBean job) {
        //Get job id key as byte array.
        byte[] jobBytes = new byte[1];
        jobBytes[0] = new Integer(job.getId()).byteValue();
        
        try {
            //Set up data entries and bindings.
            DatabaseEntry key = new DatabaseEntry(jobBytes);
            DatabaseEntry data = new DatabaseEntry();
            StoredClassCatalog classCtlg = new StoredClassCatalog(db);
            EntryBinding dataBinding = new SerialBinding(classCtlg, JobBean.class);
            
            //Retrieve the JobBean from the db_jobs database and return it.
            if (db.get(null, key, data, LockMode.DEFAULT) == OperationStatus.SUCCESS) {
                return (JobBean) dataBinding.entryToObject(data);
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public Map<Integer, JobBean> getJobs() {
        Cursor cursor = null;
        try {
            //Open cursor to iterate through all jobs.
            cursor = db.openCursor(null, null);

            //Set up data entries and bindings.
            DatabaseEntry foundKey = new DatabaseEntry();
            DatabaseEntry foundData = new DatabaseEntry();
            StoredClassCatalog classCtlg = new StoredClassCatalog(db);
            EntryBinding dataBinding = new SerialBinding(classCtlg, JobBean.class);
            
            //Cursor through the db_jobs and retrieve all JobBean objects.
            Map<Integer, JobBean> jobs = new TreeMap<Integer, JobBean>();
            while (cursor.getNext(foundKey, foundData, LockMode.DEFAULT) == OperationStatus.SUCCESS) {
                JobBean job = (JobBean) dataBinding.entryToObject(foundData);
                jobs.put(job.getId(), job);
            }
            
            return jobs;
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (DatabaseException e) {
            e.printStackTrace();
        } finally {
            try {
                if(cursor != null) cursor.close();
            } catch (DatabaseException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public boolean storeJob(JobBean job) {
        //Get job id key as byte array.
        byte[] jobBytes = new byte[1];
        jobBytes[0] = new Integer(job.getId()).byteValue();
        
        try {
            //Set up data entries and bindings.
            DatabaseEntry key = new DatabaseEntry(jobBytes);
            DatabaseEntry entry = new DatabaseEntry();
            StoredClassCatalog classCtlg = new StoredClassCatalog(db);
            EntryBinding dataBinding = new SerialBinding(classCtlg, JobBean.class);
            dataBinding.objectToEntry(job, entry);
            
            //Store JobBean in the db_jobs database.
            if (db.put(null, key, entry) == OperationStatus.SUCCESS) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}
